package com.qf.utils;

import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.jsonwebtoken.*;

import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;
import java.util.Calendar;
import java.util.UUID;

public class JWTUtils {

    private static final String JWT_PAYLOAD_USER_KEY = "user";

    /**
     * 私钥加密token
     * @param userInfo   载荷中的数据
     * @param privateKey 私钥
     * @param expire     过期时间，单位分钟
     * @return JWT
     */
    public static String generateTokenExpireInMinutes(Object userInfo, PrivateKey privateKey, int expire) {
        //计算过期时间
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MINUTE,expire);

        return Jwts.builder()
                .claim(JWT_PAYLOAD_USER_KEY, JSONUtil.toJsonStr(userInfo))
                .setId(new String(Base64.getEncoder().encode(UUID.randomUUID().toString().getBytes())))
                .setExpiration(c.getTime())
                .signWith(privateKey, SignatureAlgorithm.RS256)
                .compact();
    }

    /**
     * 私钥加密token
     * @param userInfo   载荷中的数据
     * @param privateKey 私钥
     * @param expire     过期时间，单位秒
     * @return JWT
     */
    public static String generateTokenExpireInSeconds(Object userInfo, PrivateKey privateKey, int expire) {
        //计算过期时间
        Calendar c = Calendar.getInstance();
        c.add(Calendar.SECOND,expire);

        return Jwts.builder()  //{"user":"{id:12,name:jack}"}
                .claim(JWT_PAYLOAD_USER_KEY, JSONUtil.toJsonStr(userInfo))
                .setId(new String(Base64.getEncoder().encode(UUID.randomUUID().toString().getBytes())))
                .setExpiration(c.getTime())
                .signWith(privateKey, SignatureAlgorithm.RS256)
                .compact();
    }

    /**
     * 获取token中的用户信息
     *
     * @param token     用户请求中的令牌
     * @param publicKey 公钥
     * @return 用户信息
     */
    public static Object getInfoFromToken(String token, PublicKey publicKey, Class c) 
        throws ExpiredJwtException,Exception {
        //解析token
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(publicKey).parseClaimsJws(token);
        Claims body = claimsJws.getBody();
        String jsonStr = (String) body.get(JWT_PAYLOAD_USER_KEY);
        Object o = new ObjectMapper().readValue(jsonStr, c);
        return o;
    }

    public static Object getInfoFromToken(String token,String publicKey,Class c)
        throws ExpiredJwtException,Exception{
        PublicKey publicKey1 = RsaUtils.getPublicKey(publicKey);
        Object o = getInfoFromToken(token, publicKey1, c);
        return o;
    }

}